﻿#region

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Data.Common;
#endregion

namespace ZhhbSoft.Data
{
    /// <summary>
    /// 数据库操作提供类
    /// 本类型为抽象类，具体类需要实现其创建数据库连接、适配器、查询参数等方法
    /// </summary>
    public abstract class DbProvider : IDisposable
    {
        public static T SqlDecode<T>(object value)
        {
            if (value == null || value == DBNull.Value)
            {
                return default(T);
            }
            else
            {
                return (T)value;
            }
        }

        #region 字段
        private static readonly Hashtable ParamCache = Hashtable.Synchronized(new Hashtable());
        /// <summary>
        /// 排序关键字
        /// </summary>
        private const string ORDERBY = " order by ";
        /// <summary>
        /// 选择关键字
        /// </summary>
        private const string SELECT = "select";

        /// <summary>
        /// 最后一次执行的查询语句
        /// </summary>
        private static string _lastCommandText = "";

        /// <summary>
        /// 最后一个错误描述
        /// </summary>
        private static Exception _lastException;

        /// <summary>
        /// 数据库查询次数
        /// </summary>
        private static int _queryNum;

        /// <summary>
        /// 数据库对象前缀
        /// </summary>
        private string _dataBasePrefix = "";

        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        protected string _strRawConnectionString = "";

        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        protected string _strConnectionString = "";

        protected int _commandTimeout = 30;
        private bool _enableLog;

        private static IList<IDbDataParameter> _lastDataParameters = new List<IDbDataParameter>();

        protected bool _supportTRANSACTION;

        public IDbTransaction BeginTransaction()
        {
            return BeginTransaction(CreateConnectionWithConnectionString());
        }

        public IDbTransaction BeginTransaction(IDbConnection connection)
        {
            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }
            return connection.BeginTransaction();
        }

        public void RollBackTransaction(IDbTransaction transaction)
        {
            RollBackTransaction(transaction, false);
        }

        public void RollBackTransaction(IDbTransaction transaction, bool closeConnection)
        {
            try
            {
                var conn = transaction.Connection;
                transaction.Rollback();
                if (closeConnection)
                {
                    conn.Close();
                }
            }
            catch (Exception)
            {

            }
        }

        public void CommitTransaction(IDbTransaction transaction)
        {
            CommitTransaction(transaction, false);
        }

        public void CommitTransaction(IDbTransaction transaction, bool closeConnection)
        {
            try
            {
                var conn = transaction.Connection;
                transaction.Commit();
                if (closeConnection)
                {
                    conn.Close();
                }
            }
            catch (Exception)
            {

            }
        }
        #endregion

        #region 属性

        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        public string StrConnectionString
        {
            get
            {
                if (string.IsNullOrEmpty(_strConnectionString) && !string.IsNullOrEmpty(_strRawConnectionString))
                {
                    _strConnectionString = CreateConnectionString(_strRawConnectionString);
                }
                return _strConnectionString;
            }
            set
            {
                _strConnectionString = "";
                _strRawConnectionString = value;
            }
        }

        /// <summary>
        /// 最后一次错误描述
        /// </summary>
        public static Exception LastException
        {
            get { return _lastException; }
            set { _lastException = value; }
        }

        /// <summary>
        /// 最后一次查询语句
        /// </summary>
        public static string LastCommandText
        {
            get { return _lastCommandText; }
            set { _lastCommandText = value; }
        }

        /// <summary>
        /// 数据查询执行次数
        /// </summary>
        public static int QueryNum
        {
            get { return _queryNum; }
            set { _queryNum = value; }
        }

        /// <summary>
        /// 数据库对象前缀
        /// </summary>
        public string DataBasePrefix
        {
            get { return _dataBasePrefix; }
            set { _dataBasePrefix = value; }
        }

        public bool EnableLog
        {
            get { return _enableLog; }
            set { _enableLog = value; }
        }

        public static IList<IDbDataParameter> LastDataParameters
        {
            get { return _lastDataParameters; }
            set { _lastDataParameters = value; }
        }


        public int CommandTimeout
        {
            get { return _commandTimeout; }
            set { _commandTimeout = value; }
        }
        public event DataError Error;
        public bool SupportTRANSACTION
        {
            get
            {
                return _supportTRANSACTION;
            }
        }

        public virtual long DataFileSize
        {
            get { return 0; }
        }
        #endregion
        public virtual string CreateConnectionString(params string[] strItems)
        {
            return strItems[0];
        }

        protected void OnError(Exception ex)
        {
            _lastException = ex;
            var exception = new DbProviderException(ex) { Source = ex.Source };
            if (Error != null)
            {
                Error(exception);
            }
            else
            {
                throw exception;
            }

        }
        public static DbProvider CreateDbProvider(string name)
        {
            ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[name];
            string strProviderName = connectionStringSettings.ProviderName;
            if (string.IsNullOrEmpty(strProviderName))
            {
                throw new Exception("ProviderName不能为空");
            }
            if (strProviderName.IndexOf(",") == -1)
            {
                switch (strProviderName)
                {
                    case "System.Data.SqlClient":
                        {
                            strProviderName = "ZhhbSoft.Data.MsSqlDbProvider,ZhhbSoft.Data.MsSqlDbProvider";
                            break;
                        }
                    case "System.Data.OleDb":
                        {
                            strProviderName = "ZhhbSoft.Data.OleDbDbProvider,ZhhbSoft.Data.OleDbDbProvider";
                            break;
                        }
                    case "System.Data.OleDb.MsAccess":
                        {
                            strProviderName = "ZhhbSoft.Data.MsAccessDbProvider,ZhhbSoft.Data.MsAccessDbProvider";
                            break;
                        }
                    case "System.Data.Odbc":
                        {
                            strProviderName = "ZhhbSoft.Data.OdbcDbProvider,ZhhbSoft.Data.OdbcDbProvider";
                            break;
                        }
                    case "System.Data.Odbc.MsVFoxPro":
                        {
                            strProviderName = "ZhhbSoft.Data.MsVFoxProDbProvider,ZhhbSoft.Data.MsVFoxProDbProvider";
                            break;
                        }
                    case "System.Data.OracleClient":
                        {
                            strProviderName = "ZhhbSoft.Data.OdbcDbProvider,ZhhbSoft.Data.OdbcDbProvider";
                            break;
                        }
                }
            }
            Type type = Type.GetType(strProviderName);
            if (type == null)
            {
                if (strProviderName.IndexOf(",") == -1)
                {
                    type = Type.GetType(strProviderName + "," + strProviderName);
                }
                if (type == null)
                {
                    throw new Exception("未找到该数据提供服务：" + strProviderName);
                }
            }
            return (DbProvider)Activator.CreateInstance(type,
                   new object[] { connectionStringSettings.ConnectionString });
        }
        #region 构造函数

        /// <summary>
        /// 构造函数，未初始化数据库连接串
        /// </summary>
        protected DbProvider()
            : this("")
        {
        }

        /// <summary>
        /// 构造函数，初始化数据库连接串
        /// </summary>
        /// <param name="strConnectionString">初始数据库连接串</param>
        protected DbProvider(string strConnectionString)
        {
            if (strConnectionString == null)
            {
                OnError(new ArgumentNullException("strConnectionString"));
                return;
            }
            _strRawConnectionString = strConnectionString;
        }

        #endregion

        #region 抽象函数，由子类实现

        /// <summary>
        /// 创建数据库连接
        /// </summary>
        /// <returns></returns>
        protected abstract IDbConnection CreateConnection();

        /// <summary>
        /// 创建数据库命令对象
        /// </summary>
        /// <returns></returns>
        public abstract IDbCommand CreateCommand();



        /// <summary>
        /// 创建数据适配器
        /// </summary>
        /// <param name="cmd">需要执行的命令对象</param>
        /// <returns></returns>
        protected abstract DbDataAdapter CreateDataAdapter(IDbCommand cmd);

        /// <summary>
        /// 创建执行参数
        /// </summary>
        /// <returns></returns>
        public IDbDataParameter CreateParameter()
        {
            return CreateDataParameter();
        }
        /// <summary>
        /// 创建执行参数
        /// </summary>
        /// <returns></returns>
        protected abstract IDbDataParameter CreateDataParameter();

        public virtual void ChangeDatabase(string dbName)
        { }
        #endregion

        #region 方法

        public void Close() { }
        #region CreateDataParameter 返回查询参数

        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName)
        {
            IDbDataParameter dataParameter = CreateDataParameter();
            dataParameter.ParameterName = parameterName;
            return dataParameter;
        }

        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="dbType">参数数据类型</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName);
            dataParameter.DbType = dbType;
            return dataParameter;
        }

        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="dbType">参数数据类型</param>
        /// <param name="parameterDirection">参数数据传递方向</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType, ParameterDirection parameterDirection)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, dbType);
            dataParameter.Direction = parameterDirection;
            return dataParameter;
        }
        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="parameterDirection">参数数据传递方向</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, ParameterDirection parameterDirection)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, null);
            dataParameter.Direction = parameterDirection;
            return dataParameter;
        }
        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType, int size, ParameterDirection parameterDirection)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, dbType, parameterDirection);
            if (size != 0)
            {
                dataParameter.Size = size;
            }
            return dataParameter;
        }

        public IDbDataParameter CreateDataParameter(string parameterName, ParameterDirection parameterDirection, object value)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, parameterDirection);
            dataParameter.Value = value;
            return dataParameter;
        }

        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType, int size, ParameterDirection parameterDirection, object value)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, dbType, size, parameterDirection);
            dataParameter.Value = value;
            return dataParameter;
        }

        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="value">参数值</param>
        /// <param name="dbType">参数数据类型</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, object value, DbType dbType)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, value);
            dataParameter.DbType = dbType;
            return dataParameter;
        }
        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, object value)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName);
            dataParameter.Value = value;
            return dataParameter;
        }
        public IDbDataParameter CreateDataParameter(string parameterName, object value, Type type)
        {
            return CreateDataParameter(parameterName, value, GetDbType(type));
        }

        public static DbType GetDbType(Type type)
        {
            if (type == typeof(short))
            {
                return DbType.Int16;
            }
            if (type == typeof(int))
            {
                return DbType.Int32;
            }
            if (type == typeof(long))
            {
                return DbType.Int64;
            }
            if (type == typeof(DateTime))
            {
                return DbType.DateTime;
            }
            if (type == typeof(Boolean))
            {
                return DbType.Boolean;
            }
            if (type == typeof(float))
            {
                return DbType.Single;
            }
            if (type == typeof(double))
            {
                return DbType.Double;
            }
            if (type == typeof(double))
            {
                return DbType.Double;
            }
            return DbType.String;
        }
        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="dbType">参数数据类型</param>
        /// <param name="size"></param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType, int size, object value)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, value, dbType);
            if (size != 0)
            {
                dataParameter.Size = size;
            }
            return dataParameter;
        }
        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="dbType">参数数据类型</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType, object value)
        {
            return CreateDataParameter(parameterName, value, dbType);
        }
        /// <summary>
        /// CreateDataParameter 返回查询参数
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <param name="dbType">参数数据类型</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public IDbDataParameter CreateParameter(string parameterName, DbType dbType, object value)
        {
            return CreateDataParameter(parameterName, value, dbType);
        }
        /// <summary>
        /// 传入输入参数
        /// </summary>
        /// <param name="parameterName">存储过程名称</param>
        /// <param name="value">参数值</param>
        /// <returns>新的 parameter 对象</returns>
        public IDbDataParameter MakeInParam(string parameterName, object value)
        {
            return CreateDataParameter(parameterName, DbType.String, ParameterDirection.Input, value);
        }

        public IDbDataParameter CreateDataParameter(string parameterName, DbType dbType, ParameterDirection parameterDirection, object value)
        {
            IDbDataParameter dataParameter = CreateDataParameter(parameterName, dbType, parameterDirection);
            dataParameter.Value = value;
            return dataParameter;
        }
        /// <summary>
        /// 传入输入参数
        /// </summary>
        /// <param name="parameterName">存储过程名称</param>
        /// <param name="size">参数大小</param>
        /// <param name="value">参数值</param>
        /// <returns>新的 parameter 对象</returns>
        public IDbDataParameter MakeInParam(string parameterName, int size, object value)
        {
            return CreateDataParameter(parameterName, DbType.String, size, ParameterDirection.Input, value);
        }
        /// <summary>
        /// 传入输入参数
        /// </summary>
        /// <param name="parameterName">存储过程名称</param>
        /// <param name="dbType">参数类型</param></param>
        /// <param name="size">参数大小</param>
        /// <param name="value">参数值</param>
        /// <returns>新的 parameter 对象</returns>
        public IDbDataParameter MakeInParam(string parameterName, DbType dbType, int size, object value)
        {
            return CreateDataParameter(parameterName, dbType, size, ParameterDirection.Input, value);
        }

        /// <summary>
        /// 传入返回值参数
        /// </summary>
        /// <param name="parameterName">存储过程名称</param>
        /// <param name="dbType">参数类型</param>
        /// <param name="size">参数大小</param>
        /// <returns>新的 parameter 对象</returns>
        public IDbDataParameter MakeOutParam(string parameterName, DbType dbType, int size)
        {
            return CreateDataParameter(parameterName, dbType, size, ParameterDirection.Output);
        }
        /// <summary>
        /// 传入返回值参数
        /// </summary>
        /// <param name="parameterName">存储过程名称</param>
        /// <returns>新的 parameter 对象</returns>
        public IDbDataParameter MakeOutParam(string parameterName)
        {
            return CreateDataParameter(parameterName, ParameterDirection.Output);
        }

        /// <summary>
        /// 传入返回值参数
        /// </summary>
        /// <param name="parameterName">存储过程名称</param>
        /// <param name="dbType">参数类型</param>
        /// <param name="size">参数大小</param>
        /// <returns>新的 parameter 对象</returns>
        public IDbDataParameter MakeReturnParam(string parameterName, DbType dbType, int size)
        {
            return CreateDataParameter(parameterName, dbType, size, ParameterDirection.ReturnValue, null);
        }


        #endregion

        #region ExecuteNonQuery 执行查询，返回影响到的数据条数

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="cmd">命令对象</param>
        /// <returns></returns>
        public int ExecuteNonQuery(IDbCommand cmd)
        {
            object returnValue;
            return ExecuteNonQuery(cmd, out returnValue);
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="cmd">命令对象</param>
        /// <param name="returnValue"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(IDbCommand cmd, out object returnValue)
        {
            return ExecuteNonQuery(null, cmd, out returnValue);
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="cmd">命令对象</param>
        /// <param name="transaction"></param>
        /// <param name="returnValue"></param>
        /// <returns></returns>
        public virtual int ExecuteNonQuery(IDbTransaction transaction, IDbCommand cmd, out object returnValue)
        {
            returnValue = 0;
            try
            {
                RebulidCommandParameter(cmd);
                LogDbProviderCommandText(cmd);
                _queryNum++;
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                if (cmd.Connection.State != ConnectionState.Open)
                {
                    cmd.Connection.Open();
                }
                cmd.CommandTimeout = _commandTimeout;
                int rowAffected = cmd.ExecuteNonQuery();
                return rowAffected;
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return -1;
            }
            finally
            {
                if (transaction == null || transaction.Connection != cmd.Connection)
                {
                    if (cmd.Connection != null)
                    {
                        if (cmd.Connection.State == ConnectionState.Open)
                        {
                            cmd.Connection.Close();
                        }
                    }
                }
            }
        }

        public IDbConnection CreateConnectionWithConnectionString()
        {
            IDbConnection connection = CreateConnection();
            if (connection.ConnectionString == "")
            {
                connection.ConnectionString = StrConnectionString;
            }
            return connection;
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText">命令语句</param>
        /// <returns></returns>
        public int Execute(string commandText)
        {
            return ExecuteNonQuery(commandText);
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText">命令语句</param>
        /// <returns></returns>
        public int ExecuteNonQuery(string commandText)
        {
            return ExecuteNonQuery(null, commandText);
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText">命令语句</param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(IDbTransaction transaction, string commandText)
        {
            return ExecuteNonQuery(transaction, commandText, CommandType.Text);
        }
        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandTexts">命令语句</param>
        /// <returns></returns>
        public IList<int> ExecuteNonQuery(string[] commandTexts)
        {
            IList<int> ints = new List<int>();
            foreach (string commandText in commandTexts)
            {
                ints.Add(ExecuteNonQuery(commandText, CommandType.Text));
            }
            return ints;
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText">命令语句</param>
        /// <param name="commandType">明令语句类型</param>
        /// <returns></returns>
        public int ExecuteNonQuery(CommandType commandType, string commandText)
        {
            return ExecuteNonQuery(commandText, commandType);
        }

        public int ExecuteNonQuery(IDbTransaction transaction, string commandText, CommandType commandType)
        {
            return ExecuteNonQuery(transaction, commandText, commandType, new IDbDataParameter[] { });
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public virtual int Execute(string commandText, params object[] parameters)
        {
            return ExecuteNonQuery(commandText, CommandType.StoredProcedure, parameters);
        }
        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string commandText, params object[] parameters)
        {
            object returnValue;
            return ExecuteNonQuery(commandText, out returnValue, parameters);
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="returnValue"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string commandText, out object returnValue, params object[] parameters)
        {
            return ExecuteNonQuery(commandText, out returnValue, CommandType.StoredProcedure, parameters);
        }
        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public object RunProc(string commandText, params object[] parameters)
        {
            object returnValue;
            ExecuteNonQuery(commandText, out returnValue, parameters);
            return returnValue;
        }
        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <param name="dataReader"></param>
        /// <returns></returns>
        public IDataReader RunProc(string commandText, object[] parameters, out IDataReader dataReader)
        {
            dataReader = GetDataReader(commandText, parameters);
            return dataReader;
        }
        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="dataReader"></param>
        /// <returns></returns>
        public IDataReader RunProc(string commandText, out IDataReader dataReader)
        {
            dataReader = GetDataReader(commandText, CommandType.StoredProcedure, new IDbDataParameter[] { });
            return dataReader;
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string commandText, IDbDataParameter[] parameters, CommandType commandType)
        {
            return ExecuteNonQuery(commandText, commandType, parameters);
        }

        /// <summary>
        /// ExecuteNonQuery 执行查询，返回影响到的数据条数
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="commandType"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(CommandType commandType, string commandText, params object[] parameters)
        {

            return ExecuteNonQuery(commandText, commandType, parameters);
        }

        public int ExecuteNonQuery(string commandText, CommandType commandType, params object[] parameters)
        {
            return ExecuteNonQuery(null, commandText, commandType, parameters);
        }

        public int ExecuteNonQuery(IDbTransaction transaction, string commandText, CommandType commandType, params object[] parameters)
        {
            object returnValue;
            return ExecuteNonQuery(transaction, commandText, out returnValue, commandType, parameters);
        }

        public int ExecuteNonQuery(string commandText, out object returnValue, CommandType commandType, params object[] parameters)
        {
            return ExecuteNonQuery(null, commandText, out returnValue, commandType, parameters);
        }

        public int ExecuteNonQuery(IDbTransaction transaction, string commandText, out object returnValue, CommandType commandType, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return ExecuteNonQuery(transaction, cmd, out returnValue);
        }

        #endregion

        #region GetDataReader 执行查询，返回高效的DataReader

        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public IDataReader GetDataReader(IDbCommand cmd)
        {
            return GetDataReader(null, cmd);
        }

        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public IDataReader GetDataReader(IDbTransaction transaction, IDbCommand cmd)
        {
            try
            {
                RebulidCommandParameter(cmd);
                LogDbProviderCommandText(cmd);
                _queryNum++;
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                if (cmd.Connection.State != ConnectionState.Open)
                {
                    cmd.Connection.Open();
                }
                cmd.CommandTimeout = _commandTimeout;
                return cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return null;
            }
        }

        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="commandText"></param>
        /// <returns></returns>
        public IDataReader GetReader(string commandText)
        {
            return GetDataReader(commandText);
        }
        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="commandText"></param>
        /// <returns></returns>
        public IDataReader GetDataReader(string commandText)
        {
            return GetDataReader(commandText, CommandType.Text);
        }

        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public IDataReader GetDataReader(string commandText, CommandType commandType)
        {
            return GetDataReader(commandText, commandType, new IDbDataParameter[] { });
        }

        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IDataReader GetReader(string commandText, params object[] parameters)
        {
            return GetDataReader(commandText, CommandType.StoredProcedure, parameters);
        }
        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IDataReader GetDataReader(string commandText, params object[] parameters)
        {
            return GetDataReader(commandText, CommandType.StoredProcedure, parameters);
        }

        public IDataReader GetDataReader(string commandText, IDbDataParameter[] parameters, CommandType commandType)
        {
            return GetDataReader(commandText, commandType, parameters);
        }

        /// <summary>
        /// GetDataReader 执行查询，返回高效的DataReader
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="commandType"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IDataReader GetDataReader(string commandText, CommandType commandType, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetDataReader(cmd);
        }

        #endregion

        #region GetSubDataTable 执行查询，返回分页DataTable

        public DataTable GetSubDataTable(IDbCommand cmd, int currentPage, int pageSize)
        {
            return GetSubDataTable(null, cmd, currentPage, pageSize);
        }

        public DataTable GetSubDataTable(IDbTransaction transaction, IDbCommand cmd, int currentPage, int pageSize)
        {
            try
            {
                int beginPoint = int.MinValue;
                int endPoint = int.MaxValue;
                if (pageSize != 0)
                {
                    beginPoint = (currentPage - 1) * pageSize;
                    endPoint = currentPage * pageSize;
                }
                _queryNum++;
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                IDataReader sqlread = GetDataReader(cmd);
                var dt = new DataTable();
                int fieldcount = sqlread.FieldCount;
                for (int i = 0; i < fieldcount; i++)
                {
                    dt.Columns.Add(sqlread.GetName(i), sqlread.GetFieldType(i));
                }
                dt.BeginLoadData();
                var objs = new object[fieldcount];

                for (int i = 0; i < endPoint && sqlread.Read(); i++)
                {
                    if (i < beginPoint)
                    {
                        continue;
                    }
                    if (i >= endPoint)
                    {
                        break;
                    }
                    sqlread.GetValues(objs);
                    dt.LoadDataRow(objs, true);
                }
                sqlread.Close();
                dt.EndLoadData();
                return dt;
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return null;
            }
            finally
            {
                if (transaction == null || transaction != cmd.Connection)
                {
                    if (cmd.Connection != null)
                    {
                        if (cmd.Connection.State == ConnectionState.Open)
                        {
                            cmd.Connection.Close();
                        }
                    }
                }
            }
        }

        public DataTable GetSubDataTable(string commandText, int currentPage, int pageSize)
        {
            try
            {
                string strPagedCommandText = GetPagedSQL(commandText, currentPage, pageSize);
                return GetDataTable(strPagedCommandText);
            }
            catch
            {
                return GetSubDataTable(commandText, currentPage, pageSize, CommandType.Text);
            }
        }

        public DataTable GetSubDataTable(string commandText, int currentPage, int pageSize, CommandType commandType)
        {
            return GetSubDataTable(commandText, currentPage, pageSize, commandType, new IDbDataParameter[] { });
        }

        public DataTable GetSubDataTable(string commandText, int currentPage, int pageSize,
                                         params object[] parameters)
        {
            return GetSubDataTable(commandText, currentPage, pageSize, CommandType.StoredProcedure, parameters);
        }

        public DataTable GetSubDataTable(string commandText, int currentPage, int pageSize, IDbDataParameter[] parameters,
                                         CommandType commandType)
        {
            return GetSubDataTable(commandText, currentPage, pageSize, commandType, parameters);
        }

        public DataTable GetSubDataTable(string commandText, int currentPage, int pageSize, CommandType commandType,
                                         params object[] parameters)
        {
            if (commandText == "")
            {
                return null;
            }
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetSubDataTable(cmd, currentPage, pageSize);
        }

        #endregion

        #region GetDataSet 执行查询，返回DataSet

        public DataSet GetDataSet(IDbCommand cmd)
        {
            return GetDataSet(cmd, "");
        }

        public DataSet GetDataSet(IDbCommand cmd, string tabName)
        {
            return GetDataSet(cmd, null, tabName);
        }

        public DataSet GetDataSet(IDbCommand cmd, DataSet dataSet)
        {
            return GetDataSet(cmd, dataSet, "");
        }

        public DataSet GetDataSet(IDbCommand cmd, DataSet dataSet, string tabName)
        {
            return GetDataSet(cmd, dataSet, tabName, true);
        }

        public DataSet GetDataSet(IDbCommand cmd, DataSet dataSet, string tabName, bool clearData)
        {
            return GetDataSet(null, cmd, dataSet, tabName, clearData);
        }

        public DataSet GetDataSet(IDbTransaction transaction, IDbCommand cmd, DataSet dataSet, string tabName, bool clearData)
        {
            try
            {
                if (tabName == "")
                {
                    tabName = Guid.NewGuid().ToString().Substring(0, 20);
                }
                RebulidCommandParameter(cmd);
                LogDbProviderCommandText(cmd);
                _queryNum++;
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                cmd.CommandTimeout = _commandTimeout;
                DbDataAdapter sqlDar = CreateDataAdapter(cmd);
                DataSet ds = dataSet ?? new DataSet();
                if (cmd.Connection.State != ConnectionState.Open)
                {
                    cmd.Connection.Open();
                }
                if (clearData && ds.Tables.Contains(tabName))
                {
                    ds.Tables[tabName].Clear();
                }
                sqlDar.Fill(ds, tabName);
                return ds;
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return null;
            }
            finally
            {
                if (transaction == null || transaction != cmd.Connection)
                {
                    if (cmd.Connection != null)
                    {
                        if (cmd.Connection.State == ConnectionState.Open)
                        {
                            cmd.Connection.Close();
                        }
                    }
                }
            }
        }

        public DataSet GetDataSet(string commandText)
        {
            return GetDataSet(commandText, CommandType.Text);
        }

        public DataSet GetDataSet(CommandType commandType, string commandText)
        {
            return GetDataSet(commandText, commandType);
        }
        public DataSet GetDataSet(string commandText, CommandType commandType)
        {
            return GetDataSet(commandText, commandType, new IDbDataParameter[] { });
        }

        public DataSet GetDataSet(string commandText, string tabName)
        {
            return GetDataSet(commandText, CommandType.Text, null, tabName);
        }
        public DataSet GetDataSet(string commandText, string tabName, params object[] parameters)
        {
            return GetDataSet(commandText, null, tabName, parameters);
        }

        public DataSet GetDataSet(string commandText, DataSet dataSet, string tabName)
        {
            return GetDataSet(commandText, CommandType.Text, dataSet, tabName);
        }
        public DataSet GetDataSet(string commandText, DataSet dataSet, string tabName, params object[] parameters)
        {
            return GetDataSet(commandText, CommandType.StoredProcedure, dataSet, tabName, parameters);
        }

        public DataSet GetDataSet(string commandText, IDbDataParameter[] parameters, CommandType commandType)
        {
            return GetDataSet(commandText, commandType, parameters);
        }

        public DataSet GetDataSet(string commandText, params object[] parameters)
        {
            return GetDataSet(commandText, CommandType.StoredProcedure, parameters);
        }

        public DataSet GetDataSet(string commandText, IDbDataParameter[] parameters, string tabName)
        {
            return GetDataSet(commandText, tabName, parameters);
        }

        public DataSet GetDataSet(CommandType commandType, string commandText, params object[] parameters)
        {
            return GetDataSet(commandText, commandType, parameters);
        }

        public DataSet GetDataSet(string commandText, CommandType commandType, params object[] parameters)
        {
            return GetDataSet(commandText, commandType, null, parameters);
        }

        public DataSet GetDataSet(string commandText, DataSet dataSet, params object[] parameters)
        {
            return GetDataSet(commandText, CommandType.StoredProcedure, dataSet, parameters);
        }

        public DataSet GetDataSet(string commandText, CommandType commandType, DataSet dataSet, params object[] parameters)
        {
            return GetDataSet(commandText, commandType, dataSet, "", parameters);
        }

        public DataSet GetDataSet(string commandText, CommandType commandType, DataSet dataSet, string tabName, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetDataSet(cmd, dataSet, tabName);
        }

        #endregion

        #region GetDataTable 执行查询，返回DataTable

        public DataTable GetDataTable(IDbCommand cmd)
        {
            return GetSubDataTable(cmd, 0, 0);
        }

        public DataTable GetDataTable(string commandText)
        {
            return GetDataTable(commandText, CommandType.Text);
        }

        public DataTable GetDataTable(string commandText, CommandType commandType)
        {
            return GetDataTable(commandText, commandType, new IDbDataParameter[] { });
        }

        public DataTable GetDataTable(string commandText, params object[] parameters)
        {
            return GetDataTable(commandText, CommandType.StoredProcedure, parameters);
        }

        public DataTable GetDataTable(string commandText, IDbDataParameter[] parameters, CommandType commandType)
        {
            return GetDataTable(commandText, commandType, parameters);
        }

        public DataTable GetDataTable(string commandText, CommandType commandType, params object[] parameters)
        {
            return GetSubDataTable(commandText, 0, 0, commandType, parameters);
        }

        #endregion

        #region GetIList<T> 执行查询，返回IList<T>泛型列表

        public IList<T> GetIList<T>(string commandText)
        {
            return GetIList<T>(commandText, CommandType.Text);
        }
        public IList<object> GetIList(string commandText, Type type)
        {
            return GetIList<object>(commandText, CommandType.Text, type);
        }

        public IList<T> GetIList<T>(string commandText, params object[] parameters)
        {
            return GetIList<T>(commandText, CommandType.StoredProcedure, parameters);
        }

        public IList<T> GetIList<T>(string commandText, CommandType commandType, params object[] parameters)
        {
            return GetSubIList<T>(commandText, 0, 0, commandType, parameters);
        }

        public IList<T> GetIList<T>(string commandText, CommandType commandType, Type type)
        {
            return GetSubIList<T>(commandText, 0, 0, commandType, type);
        }

        public IList<T> GetSubIList<T>(string commandText, int currentPage, int pageSize, params object[] parameters)
        {
            return GetSubIList<T>(commandText, currentPage, pageSize, CommandType.StoredProcedure, parameters);
        }

        public IList<T> GetSubIList<T>(string commandText, int currentPage, int pageSize, CommandType commandType, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetSubIList<T>(cmd, currentPage, pageSize);
        }
        public IList<T> GetSubIList<T>(string commandText, int currentPage, int pageSize, CommandType commandType, Type type, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetSubIList<T>(cmd, type, currentPage, pageSize);
        }

        public IList<T> GetSubIList<T>(IDbCommand cmd, Type type, int currentPage, int pageSize)
        {
            object obj = null;
            IList<object> list = GetSubIList(cmd, ref obj, type, currentPage, pageSize);
            IList<T> list2 = new List<T>();
            foreach (object obj2 in list)
            {
                list2.Add((T)obj2);
            }
            return list2;
        }

        public IList<object> GetSubIList(IDbCommand cmd, Type type, int currentPage, int pageSize)
        {
            object obj = null;
            return GetSubIList(cmd, ref obj, type, currentPage, pageSize);
        }

        public IList<object> GetSubIList(IDbCommand cmd, ref object obj, Type type, int currentPage, int pageSize)
        {
            return GetSubIList(null, cmd, ref obj, type, currentPage, pageSize);
        }

        public IList<object> GetSubIList(IDbTransaction transaction, IDbCommand cmd, ref object obj, Type type, int currentPage, int pageSize)
        {
            try
            {
                int beginPoint = int.MinValue;
                int endPoint = int.MaxValue;
                if (pageSize != 0)
                {
                    beginPoint = (currentPage - 1) * pageSize;
                    endPoint = currentPage * pageSize;
                }
                _queryNum++;
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                IDataReader sqlread = GetDataReader(cmd);
                IList<object> listT = new List<object>();

                MemberInfo[] pis = type.GetMembers(
                    BindingFlags.Public
                    | BindingFlags.Instance
                    | BindingFlags.SetProperty
                    | BindingFlags.GetField);
                for (int i = 0; i < endPoint && sqlread.Read(); i++)
                {
                    if (i < beginPoint)
                    {
                        continue;
                    }
                    if (i >= endPoint)
                    {
                        break;
                    }
                    object tObj;
                    if (obj != null && i == 0)
                    {
                        tObj = obj;
                    }
                    else
                    {
                        try
                        {
                            tObj = Activator.CreateInstance(type, new object[] { this });
                        }
                        catch (Exception)
                        {
                            tObj = Activator.CreateInstance(type, new object[] { });
                        }
                    }
                    for (int j = 0; j < pis.Length; j++)
                    {
                        try
                        {
                            Attribute[] dataMembers = Attribute.GetCustomAttributes(pis[j], typeof(DataMember));
                            if (dataMembers != null && dataMembers.Length > 0)
                            {
                                if (((DataMember)dataMembers[0]).FieldName == "")
                                {
                                    ((DataMember)dataMembers[0]).FieldName = pis[j].Name;
                                }
                                try
                                {
                                    SetPropertyORFieldValue(tObj, pis[j], sqlread[((DataMember)dataMembers[0]).FieldName]);
                                }
                                catch (Exception)
                                {
                                }
                            }
                        }
                        catch
                        {
                        }
                    }
                    listT.Add(tObj);
                    if (i < beginPoint)
                    {
                        continue;
                    }
                    if (i >= endPoint)
                    {
                        break;
                    }
                }

                sqlread.Close();
                return listT;
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return null;
            }
            finally
            {
                if (transaction == null || transaction != cmd.Connection)
                {
                    if (cmd.Connection != null)
                    {
                        if (cmd.Connection.State == ConnectionState.Open)
                        {
                            cmd.Connection.Close();
                        }
                    }
                }
            }
        }

        private static void SetPropertyORFieldValue(object tObj, MemberInfo memberInfo, object obj)
        {
            object objT;
            if (memberInfo is PropertyInfo)
            {
                if (((PropertyInfo)memberInfo).PropertyType == typeof(float))
                {
                    objT = obj != DBNull.Value ? Convert.ToSingle(obj) : 0;
                }
                else if (((PropertyInfo)memberInfo).PropertyType == typeof(int))
                {
                    objT = obj != DBNull.Value ? Convert.ToInt32(obj) : 0;
                }
                else
                {
                    objT = obj;
                }
                if (objT != DBNull.Value)
                {
                    ((PropertyInfo)memberInfo).SetValue(tObj, objT, null);
                }
            }
            else
            {
                if (((FieldInfo)memberInfo).FieldType == typeof(float))
                {
                    objT = obj != DBNull.Value ? Convert.ToSingle(obj) : 0;
                }
                else if (((FieldInfo)memberInfo).FieldType == typeof(int))
                {
                    objT = obj != DBNull.Value ? Convert.ToInt32(obj) : 0;
                }
                else
                {
                    objT = obj;
                }
                if (objT != DBNull.Value)
                {
                    ((FieldInfo)memberInfo).SetValue(tObj, objT);
                }
            }
        }

        public IList<T> GetSubIList<T>(IDbCommand cmd, int currentPage, int pageSize)
        {
            object obj = null;
            return GetSubIList<T>(cmd, ref obj, currentPage, pageSize);
        }

        public IList<T> GetSubIList<T>(IDbCommand cmd, ref object obj, int currentPage, int pageSize)
        {
            return ((List<object>)GetSubIList(cmd, ref obj, typeof(T), currentPage, pageSize)).ConvertAll(obj2 => (T)obj2);
        }
        #endregion

        #region GetObject 获取对象
        public object GetObject(IDbCommand cmd, Type type)
        {
            object obj = null;
            return GetObject(cmd, ref obj, type);
        }

        public object GetObject(IDbCommand cmd, ref object obj, Type type)
        {
            IList<object> list = GetSubIList(cmd, ref  obj, type, 0, 0);
            if (list != null && list.Count > 0)
            {
                return list[0];
            }
            return null;
        }
        public object GetObject(string commandText, ref object obj, Type type, params object[] parameters)
        {
            return GetObject(commandText, CommandType.Text, ref obj, type, parameters);
        }

        public object GetObject(string commandText, Type type)
        {
            object obj = null;
            return GetObject(commandText, ref obj, type);
        }
        public object GetObject(string commandText, Type type, params object[] parameters)
        {
            return GetObject(commandText, CommandType.StoredProcedure, type, parameters);
        }

        public object GetObject(string commandText, CommandType commandType, Type type, params object[] parameters)
        {
            object obj = null;
            return GetObject(commandText, commandType, ref obj, type, parameters);
        }

        public object GetObject(string commandText, CommandType commandType, ref object obj, Type type, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetObject(cmd, ref obj, type);
        }
        #endregion
        #region GetObject<T> 获取对象
        public T GetObject<T>(IDbCommand cmd) where T : class
        {
            IList<T> list = GetSubIList<T>(cmd, 0, 0);
            if (list != null && list.Count > 0)
            {
                return list[0];
            }
            return null;
        }

        public T GetObject<T>(string commandText) where T : class
        {
            return GetObject<T>(commandText, CommandType.Text, new IDbDataParameter[] { });
        }

        public T GetObject<T>(string commandText, params object[] parameters) where T : class
        {
            return GetObject<T>(commandText, CommandType.StoredProcedure, parameters);
        }

        public T GetObject<T>(string commandText, CommandType commandType, params object[] parameters) where T : class
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetObject<T>(cmd);
        }
        #endregion

        #region UpdateObject

        public bool UpdateObject(object tObj, Type type, string strTableName)
        {
            MemberInfo[] pis = type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.GetField);
            IList<IDbDataParameter> listDataParameters = new List<IDbDataParameter>();
            IList<IDbDataParameter> listKeyDataParameters = new List<IDbDataParameter>();
            IList<IDbDataParameter> listAutoDataParameters = new List<IDbDataParameter>();
            for (int j = 0; j < pis.Length; j++)
            {
                try
                {
                    var dataMember = (DataMember)Attribute.GetCustomAttribute(pis[j], typeof(DataMember));
                    if (dataMember != null && dataMember.SaveAble)
                    {
                        IDbDataParameter dataParameter;
                        if (dataMember.FieldName != "")
                        {
                            if (pis[j] is PropertyInfo)
                            {
                                dataParameter = CreateDataParameter("@" + dataMember.FieldName, ((PropertyInfo)pis[j]).GetValue(tObj, null));
                            }
                            else
                            {
                                dataParameter = CreateDataParameter("@" + dataMember.FieldName, ((FieldInfo)pis[j]).GetValue(tObj));
                            }
                        }
                        else
                        {
                            if (pis[j] is PropertyInfo)
                            {
                                dataParameter = CreateDataParameter("@" + pis[j].Name, ((PropertyInfo)pis[j]).GetValue(tObj, null));
                            }
                            else
                            {
                                dataParameter = CreateDataParameter("@" + pis[j].Name, ((FieldInfo)pis[j]).GetValue(tObj));
                            }
                        }
                        if (dataParameter != null)
                        {
                            if (dataMember is AutoDataMember)
                            {
                                listAutoDataParameters.Add(dataParameter);
                            }
                            else if (dataMember is KeyDataMember)
                            {
                                listKeyDataParameters.Add(dataParameter);
                            }
                            else
                            {
                                listDataParameters.Add(dataParameter);
                            }
                        }
                    }
                }
                catch
                {
                }
            }
            var dataParameters =
                new IDbDataParameter[listDataParameters.Count
                + listKeyDataParameters.Count
                + listAutoDataParameters.Count];
            string strSets = "";
            for (int i = 0; i < listDataParameters.Count; i++)
            {
                strSets += "[" + listDataParameters[i].ParameterName.Substring(1) + "]=" + listDataParameters[i].ParameterName + ",";
                dataParameters[i] = listDataParameters[i];
            }
            string strWheres = " 1=1 ";
            for (int i = 0; i < listKeyDataParameters.Count; i++)
            {
                strSets += listKeyDataParameters[i].ParameterName.Substring(1) + "=" + listKeyDataParameters[i].ParameterName + ",";
                strWheres += "and [" + listKeyDataParameters[i].ParameterName.Substring(1) + "]=" + listKeyDataParameters[i].ParameterName + " ";
                dataParameters[i + listDataParameters.Count] = listKeyDataParameters[i];
            }
            for (int i = 0; i < listAutoDataParameters.Count; i++)
            {
                strWheres += "and [" + listAutoDataParameters[i].ParameterName.Substring(1) + "]=" + listAutoDataParameters[i].ParameterName + " ";
                dataParameters[i + listDataParameters.Count + listKeyDataParameters.Count] = listAutoDataParameters[i];
            }
            if (strSets.Length > 0)
            {
                strSets = strSets.Remove(strSets.Length - 1);
                string commandText = string.Format("update [{0}] set {1} where {2}", strTableName, strSets, strWheres);

                return ExecuteNonQuery(commandText, CommandType.Text, dataParameters) > 0;
            }
            return false;
        }

        public bool UpdateObject<T>(T tObj, string strTableName) where T : class
        {
            Type type = typeof(T);
            return UpdateObject(tObj, type, strTableName);
        }
        #endregion

        #region InsertObject
        public bool InsertObject<T>(T tObj, string strTableName) where T : class
        {
            Type type = typeof(T);
            return InsertObject(tObj, type, strTableName);
        }
        public bool InsertObject(object tObj, Type type, string strTableName)
        {
            MemberInfo[] pis = type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.GetField);
            IList<IDbDataParameter> listDataParameters = new List<IDbDataParameter>();
            for (int j = 0; j < pis.Length; j++)
            {
                try
                {
                    Attribute[] dataMembers = Attribute.GetCustomAttributes(pis[j], typeof(DataMember));
                    if (dataMembers != null && dataMembers.Length > 0 && ((DataMember)dataMembers[0]).SaveAble && !(((DataMember)dataMembers[0]) is AutoDataMember))
                    {
                        if (((DataMember)dataMembers[0]).FieldName != "")
                        {
                            if (pis[j] is PropertyInfo)
                            {
                                listDataParameters.Add(CreateDataParameter("@" + ((DataMember)dataMembers[0]).FieldName, ((PropertyInfo)pis[j]).GetValue(tObj, null)));
                            }
                            else
                            {
                                listDataParameters.Add(CreateDataParameter("@" + ((DataMember)dataMembers[0]).FieldName, ((FieldInfo)pis[j]).GetValue(tObj)));
                            }
                        }
                        else
                        {
                            if (pis[j] is PropertyInfo)
                            {
                                listDataParameters.Add(CreateDataParameter("@" + pis[j].Name, ((PropertyInfo)pis[j]).GetValue(tObj, null)));
                            }
                            else
                            {
                                listDataParameters.Add(CreateDataParameter("@" + pis[j].Name, ((FieldInfo)pis[j]).GetValue(tObj)));
                            }
                        }
                    }
                }
                catch
                {
                }
            }
            string strFileds = "";
            string strValues = "";
            var dataParameters = new IDbDataParameter[listDataParameters.Count];
            if (listDataParameters.Count > 0)
            {
                for (int i = 0; i < listDataParameters.Count; i++)
                {
                    strFileds += "[" + listDataParameters[i].ParameterName.Substring(1) + "],";
                    strValues += listDataParameters[i].ParameterName + ",";
                    dataParameters[i] = listDataParameters[i];
                }
                strFileds = strFileds.Remove(strFileds.Length - 1);
                strValues = strValues.Remove(strValues.Length - 1);
                string commandText = string.Format("insert into [{0}]({1}) values({2})", strTableName, strFileds, strValues);
                return ExecuteNonQuery(commandText, CommandType.Text, dataParameters) > 0;
            }
            return false;
        }
        #endregion

        #region Delete
        public bool Delete(string commandText)
        {
            return Delete(commandText, CommandType.Text);
        }
        public bool Delete(string commandText, CommandType commandType)
        {
            return Delete(commandText, commandType, null);
        }
        public virtual bool Delete(string commandText, CommandType commandType, params object[] parameters)
        {
            return ExecuteNonQuery(commandText, commandType, parameters) > 0;

        }
        public bool Delete(string commandText, params object[] parameters)
        {
            if (parameters != null && parameters.Length > 0)
            {
                return Delete(commandText, CommandType.StoredProcedure, parameters);
            }
            return Delete(commandText, CommandType.Text, parameters);
        }

        #endregion

        #region SaveObject
        public bool SaveObject(object tObj, Type type)
        {
            return SaveObject(tObj, type, false);
        }
        public bool SaveObject(object tObj, Type type, bool isUpdate)
        {
            if (!(tObj is IAutoSaveable))
            {
                OnError(new Exception(type.Name + "不是可自动保存的类型"));
            }
            string strTableName = ((IAutoSaveable)tObj).TableName;
            return isUpdate ? UpdateObject(tObj, type, strTableName) : InsertObject(tObj, type, strTableName);
        }

        public bool SaveObject<T>(T tObj) where T : class
        {
            return SaveObject(tObj, false);
        }
        public bool SaveObject<T>(T tObj, bool isUpdate) where T : class
        {
            if (!(tObj is IAutoSaveable))
            {
                OnError(new Exception(typeof(T).Name + "不是可自动保存的类型"));
            }
            string strTableName = ((IAutoSaveable)tObj).TableName;
            return isUpdate ? UpdateObject(tObj, strTableName) : InsertObject(tObj, strTableName);
        }

        #endregion

        #region GetDataRow 执行查询，返回首行

        public DataRow GetDataRow(IDbCommand cmd)
        {
            return GetDataRow(null, cmd);
        }

        public DataRow GetDataRow(IDbTransaction transaction, IDbCommand cmd)
        {
            try
            {
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                if (cmd.Connection.State != ConnectionState.Open)
                {
                    cmd.Connection.Open();
                }
                DataTable dt = GetSubDataTable(cmd, 1, 1);
                if (dt == null || dt.Rows.Count < 1)
                {
                    return null;
                }
                else
                {
                    return dt.Rows[0];
                }
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return null;
            }
            finally
            {
                if (transaction == null || transaction != cmd.Connection)
                {
                    if (cmd.Connection != null)
                    {
                        if (cmd.Connection.State == ConnectionState.Open)
                        {
                            cmd.Connection.Close();
                        }
                    }
                }
            }
        }

        public DataRow GetDataRow(string commandText)
        {
            return GetDataRow(commandText, CommandType.Text);
        }

        public DataRow GetDataRow(string commandText, CommandType commandType)
        {
            return GetDataRow(commandText, commandType, new IDbDataParameter[] { });
        }

        public DataRow GetDataRow(string commandText, params object[] parameters)
        {
            return GetDataRow(commandText, CommandType.StoredProcedure, parameters);
        }

        public DataRow GetDataRow(string commandText, IDbDataParameter[] parameters, CommandType commandType)
        {
            return GetDataRow(commandText, commandType, parameters);
        }

        public DataRow GetDataRow(string commandText, CommandType commandType, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            AttachParameters(cmd, commandParameters);
            return GetDataRow(cmd);
        }

        #endregion

        #region ExecuteScalar 执行查询，返回首行首列

        public object ExecuteScalar(IDbCommand cmd)
        {
            return ExecuteScalar(null, cmd);
        }

        public object ExecuteScalar(IDbTransaction transaction, IDbCommand cmd)
        {
            if (cmd == null)
            {
                OnError(new ArgumentNullException("cmd"));
                return null;
            }
            try
            {
                RebulidCommandParameter(cmd);
                LogDbProviderCommandText(cmd);
                _queryNum++;
                if (cmd.Connection == null)
                {
                    if (transaction != null)
                    {
                        cmd.Connection = transaction.Connection;
                        cmd.Transaction = transaction;
                    }
                    else
                    {
                        cmd.Connection = CreateConnectionWithConnectionString();
                    }
                }
                if (cmd.Connection.State != ConnectionState.Open)
                {
                    cmd.Connection.Open();
                }
                cmd.CommandTimeout = _commandTimeout;
                return cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
                _lastCommandText = cmd.CommandText;
                _lastDataParameters.Clear();
                for (int i = 0; i < cmd.Parameters.Count; i++)
                {
                    _lastDataParameters.Add((IDbDataParameter)cmd.Parameters[i]);
                }
                OnError(ex);
                return null;
            }
            finally
            {
                if (transaction == null || transaction != cmd.Connection)
                {
                    if (cmd.Connection != null)
                    {
                        if (cmd.Connection.State == ConnectionState.Open)
                        {
                            cmd.Connection.Close();
                        }
                    }
                }
            }
        }
        public object ExecuteScalar(string commandText)
        {
            return ExecuteScalar(commandText, CommandType.Text);
        }
        public object ExecuteScalar(CommandType commandType, string commandText)
        {
            return ExecuteScalar(commandText, commandType);
        }
        public object ExecuteScalar(string commandText, CommandType commandType)
        {
            return ExecuteScalar(commandText, commandType, new IDbDataParameter[] { });
        }
        public object ExecuteScalar(string commandText, params object[] parameters)
        {
            return ExecuteScalar(commandText, CommandType.StoredProcedure, parameters);
        }
        public object ExecuteScalar(string commandText, IDbDataParameter[] parameters, CommandType commandType)
        {
            return ExecuteScalar(commandText, commandType, parameters);
        }
        public object ExecuteScalar(CommandType commandType, string commandText, params object[] parameters)
        {
            return ExecuteScalar(commandText, commandType, parameters);
        }
        public object ExecuteScalar(string commandText, CommandType commandType, params object[] parameters)
        {
            IDbDataParameter[] commandParameters;
            if (commandType == CommandType.StoredProcedure && parameters != null && parameters.Length > 0 && !(parameters[0] is IDbDataParameter))
            {
                commandParameters = GetSpParameterSet(commandText);
                AssignParameterValues(commandParameters, parameters);
            }
            else
            {
                commandParameters = CopyParameters(parameters);
            }
            IDbCommand cmd = CreateCommand();
            cmd.CommandText = commandText;
            cmd.CommandType = commandType;
            if (parameters != null && parameters.Length > 0)
            {
                AttachParameters(cmd, commandParameters);
            }
            return ExecuteScalar(cmd);
        }

        public object GetScalar(string commandText)
        {
            return ExecuteScalar(commandText);
        }
        public virtual object GetScalar(string commandText, params object[] parameters)
        {
            return ExecuteScalar(commandText, CommandType.StoredProcedure, parameters);
        }
        #endregion

        #region 其他函数

        /// <summary>
        /// 生成分页查询语句
        /// </summary>
        /// <param name="preparedSql">原始sql查询语句</param>
        /// <param name="pageIndex">当前页码，从1开始</param>
        /// <param name="pageSize">页容量</param>
        /// <returns></returns>
        public string GetPagedSQL(string preparedSql, int pageIndex, int pageSize)
        {
            return GetPagedSQL(preparedSql, pageIndex, pageSize, int.MaxValue);
        }

        /// <summary>
        /// 生成分页查询语句
        /// </summary>
        /// <param name="preparedSql">原始sql查询语句</param>
        /// <param name="pageIndex">当前页码，从1开始</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public string GetPagedSQL(string preparedSql, int pageIndex, int pageSize, int recordCount)
        {
            if (recordCount == 0)
            {
                return preparedSql;
            }
            preparedSql = preparedSql.Trim();

            #region 处理SELECT关键字

            int selectPosition = preparedSql.ToLower().IndexOf(SELECT);
            if (selectPosition != 0)
            {
                OnError(new Exception("缺少 " + SELECT + " 关键字"));
                return null;
            }
            preparedSql = preparedSql.Substring(SELECT.Length);

            #endregion

            #region 处理order by字段名

            string formattedOrder = "";
            int orderbyPosition = preparedSql.ToLower().LastIndexOf(ORDERBY.Trim().ToLower());
            if (orderbyPosition == -1)
            {
                OnError(new Exception("缺少 " + ORDERBY + " 关键字"));
                return null;
            }
            string strOrderBy = preparedSql.Substring(orderbyPosition + ORDERBY.Trim().Length).ToUpper().Trim();
            strOrderBy = Regex.Replace(strOrderBy, @"\s+", " ");
            preparedSql = preparedSql.Substring(0, orderbyPosition);

            string reversedOrder = GetReversedOrderString(strOrderBy, ref formattedOrder, true);
            #endregion

            #region 重新生成Sql语句

            string pagingSql;
            int rowsToFetch;
            if (recordCount == 0)//当指定了recordCount并且为0时
            {
                return "";
            }
            if (recordCount > 0)//当指定了recordCount时并且不为0时
            {
                int pageCount = recordCount / pageSize;
                if (recordCount > pageCount * pageSize)
                {
                    pageCount++;
                }
                if (pageIndex * 2 > pageCount)//当要取的页在靠后的位置时
                {
                    rowsToFetch = recordCount - pageSize * (pageIndex - 1);
                    if (rowsToFetch <= 0)
                    {
                        return "";
                    }
                    pagingSql = "SELECT TOP {0} * FROM (SELECT TOP {1} {2} ORDER BY {3})AS sql_qry ORDER BY {4}";
                }
                else//当要取的页在靠前的位置时
                {
                    rowsToFetch = pageSize * pageIndex;
                    pagingSql = "SELECT * FROM(SELECT TOP {0} * FROM (SELECT TOP {1} {2} ORDER BY {5})AS sql_qry ORDER BY {3})AS sql_fetch ORDER BY {4}";
                }
            }
            else//当未指定recordCount时
            {
                rowsToFetch = pageSize * pageIndex;
                pagingSql = "SELECT * FROM(SELECT TOP {0} * FROM (SELECT TOP {1} {2} ORDER BY {5})AS sql_qry ORDER BY {3})AS sql_fetch ORDER BY {4}";
            }

            string strPagedSql = String.Format(pagingSql, pageSize, rowsToFetch, preparedSql, reversedOrder,
                                               formattedOrder, strOrderBy);
            return Regex.Replace(strPagedSql, @"\s+", " ");

            #endregion
        }


        /// <summary>
        /// 转置数据表
        /// </summary>
        /// <param name="dataTableSource">原始数据表</param>
        /// <returns></returns>
        public DataTable TransposeDataTable(DataTable dataTableSource)
        {
            var dataTableResult = new DataTable();
            dataTableResult.Columns.Add(dataTableSource.Columns[0].ColumnName);
            for (int i = 0; i < dataTableSource.Rows.Count; i++)
            {
                dataTableResult.Columns.Add(dataTableSource.Rows[i][0].ToString());
            }
            for (int i = 1; i < dataTableSource.Columns.Count; i++)
            {
                DataRow dataRow = dataTableResult.NewRow();
                dataRow[0] = dataTableSource.Columns[i].ColumnName;
                for (int j = 0; j < dataTableSource.Rows.Count; j++)
                {
                    dataRow[j + 1] = dataTableSource.Rows[j][dataTableSource.Columns[i]].ToString();
                }
                dataTableResult.Rows.Add(dataRow);
            }
            return dataTableResult;
        }
        /// <summary>
        /// 编码sql语句
        /// </summary>
        /// <param name="value"></param>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public virtual string SqlEncode(object value, DbType dbType)
        {
            switch (dbType)
            {
                case DbType.String:
                    {
                        return "'" + value.ToString().Replace("'", "''") + "'";
                    }
                case DbType.Int32:
                    {
                        return Convert.ToInt32(value).ToString();
                    }
                case DbType.Date:
                    {
                        return "#" + Convert.ToDateTime(value).ToString("MM-dd-yyyy") + "#";
                    }
                case DbType.Time:
                    {
                        return "#" + Convert.ToDateTime(value).ToString("HH:mm:ss") + "#";
                    }
                case DbType.DateTime:
                    {
                        return "#" + Convert.ToDateTime(value).ToString("MM-dd-yyyy HH:mm:ss") + "#";
                    }
                default:
                    {
                        return "'" + value.ToString().Replace("'", "''") + "'";
                    }
            }
        }
        /// <summary>
        /// 处理参数
        /// </summary>
        /// <param name="command"></param>
        protected virtual void RebulidCommandParameter(IDbCommand command)
        {
            foreach (IDbDataParameter parameter in command.Parameters)
            {
                if (parameter.Value == null)
                {
                    parameter.Value = DBNull.Value;
                }
            }
        }
        /// <summary>
        /// 记录查询日志
        /// </summary>
        /// <param name="cmd"></param>
        private void LogDbProviderCommandText(IDbCommand cmd)
        {
            if (_enableLog)
            {
                var streamWriter = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\DbProvider.Log", true);
                streamWriter.WriteLine("========================================================================================================");
                streamWriter.WriteLine(DateTime.Now.ToString("[ MM-dd-yyyy HH:mm:ss ]"));
                streamWriter.WriteLine(cmd.CommandText);
                foreach (IDbDataParameter parameter in cmd.Parameters)
                {
                    streamWriter.WriteLine("\t" + parameter.ParameterName + ":" +
                                           ((parameter.DbType != DbType.Binary)
                                                ? parameter.Value.ToString()
                                                : DbType.Binary.ToString()));
                }
                streamWriter.Close();
            }

        }


        #endregion

        private static void AttachParameters(IDbCommand command, IEnumerable<IDbDataParameter> commandParameters)
        {
            foreach (IDbDataParameter parameter in commandParameters)
            {
                if ((parameter.Direction == ParameterDirection.InputOutput) && (parameter.Value == null))
                {
                    parameter.Value = DBNull.Value;
                }
                command.Parameters.Add(parameter);
            }
        }

        private static void AssignParameterValues(IDbDataParameter[] commandParameters, object[] parameterValues)
        {
            if ((commandParameters == null) || (parameterValues == null))
            {
                //do nothing if we get no data
                return;
            }

            // we must have the same number of values as we pave parameters to put them in
            if (commandParameters.Length != parameterValues.Length)
            {
                throw new ArgumentException("Parameter count does not match Parameter Value count.");
            }

            //iterate through the IDbDataParameters, assigning the values from the corresponding position in the 
            //value array
            for (int i = 0, j = commandParameters.Length; i < j; i++)
            {
                commandParameters[i].Value = parameterValues[i];
            }
        }

        #region ParameterSet
        protected virtual IDbDataParameter[] DiscoverSpParameterSet(string spName, bool includeReturnValueParameter)
        {
            return null;
        }

        public static IDbDataParameter[] CloneParameters(object[] originalParameters)
        {
            var clonedParameters = new IDbDataParameter[originalParameters.Length];
            for (int i = 0, j = originalParameters.Length; i < j; i++)
            {
                clonedParameters[i] = (IDbDataParameter)((ICloneable)originalParameters[i]).Clone();
            }
            return clonedParameters;
        }

        public static IDbDataParameter[] CopyParameters(object[] originalParameters)
        {
            if (originalParameters == null)
            {
                return null;
            }
            var copyedParameters = new IDbDataParameter[originalParameters.Length];
            for (int i = 0, j = originalParameters.Length; i < j; i++)
            {
                copyedParameters[i] = (IDbDataParameter)originalParameters[i];
            }
            return copyedParameters;
        }

        public void CacheParameterSet(string commandText, params IDbDataParameter[] commandParameters)
        {
            string hashKey = StrConnectionString + ":" + commandText;
            ParamCache[hashKey] = commandParameters;
        }

        public IDbDataParameter[] GetCachedParameterSet(string commandText)
        {
            string hashKey = StrConnectionString + ":" + commandText;

            var cachedParameters = (IDbDataParameter[])ParamCache[hashKey];

            return cachedParameters == null ? null : CopyParameters(cachedParameters);
        }

        public IDbDataParameter[] GetSpParameterSet(string spName)
        {
            return GetSpParameterSet(spName, false);
        }

        public IDbDataParameter[] GetSpParameterSet(string spName, bool includeReturnValueParameter)
        {
            string hashKey = StrConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "");

            IDbDataParameter[] cachedParameters = (IDbDataParameter[])ParamCache[hashKey] ??
                                                  (IDbDataParameter[])(ParamCache[hashKey] = DiscoverSpParameterSet(spName, includeReturnValueParameter));

            return CloneParameters(cachedParameters);
        }

        #endregion

        public virtual string DbDateFunc
        {
            get
            {
                return "";
            }
        }

        /// <summary>
        /// 时间常量
        /// </summary>
        public virtual string DbDateVar(string datetimeValue)
        {
            return "'" + datetimeValue + "'";
        }

        private static DbProvider _default;
        public static DbProvider Default
        {
            get
            {
                if (_default == null)
                {
                    string strSetting = ConfigurationManager.AppSettings["DefaultConnectionString"];
                    if (string.IsNullOrEmpty(strSetting))
                    {
                        return CreateDbProvider("Default");
                        return null;
                    }
                    _default = CreateDbProvider(strSetting);
                }
                return _default;
            }
        }
        private static DbProvider _msSqlServer;
        public static DbProvider MsSqlServer
        {
            get
            {
                if (_msSqlServer == null)
                {
                    _msSqlServer = CreateDbProvider(ConfigurationManager.AppSettings["MsSqlServerConnectionString"]);
                }
                return _msSqlServer;
            }
        }
        private static DbProvider _msAccess;
        public static DbProvider MsAccess
        {
            get
            {
                if (_msAccess == null)
                {
                    _msAccess = CreateDbProvider(ConfigurationManager.AppSettings["MsAccessConnectionString"]);
                }
                return _msAccess;
            }
        }

        /// <summary>
        /// 时间相加
        /// </summary>
        public virtual string DbDateAdd(string unit, int minuend, string datetimeValue)
        {
            return "dateadd(" + unit + ", " + minuend + ", " + datetimeValue + ")";
        }

        /// <summary>
        /// 时间间隔
        /// </summary>
        public virtual string DbDateDiff(string unit, string datetimeValue1, string datetimeValue2)
        {
            return "datediff(" + unit + ", " + datetimeValue1 + ", " + datetimeValue2 + ")";
        }

        #endregion

        #region IDisposable 成员

        public void Dispose()
        {

        }

        #endregion

        public virtual string GetDeleteCommandText(string tableName)
        {
            return "delete from [" + tableName + "]";
        }

        public virtual bool CompareOrderString(string strOrderBy, string strOrderBy2)
        {
            strOrderBy = strOrderBy.Trim();
            strOrderBy2 = strOrderBy2.Trim();
            if (strOrderBy == "" || strOrderBy2 == "")
            {
                return false;
            }
            const string delimStr = ",";
            string[] aryCols = Regex.Split(strOrderBy, delimStr);
            string[] aryCols2 = Regex.Split(strOrderBy2, delimStr);

            for (int i = 0; i < aryCols.Length; i++)
            {
                string[] colOrder = aryCols[i].Split(' ');
                string[] colOrder2 = aryCols2[i].Split(' ');
                string order = "ASC", order2 = "ASC";
                if (colOrder.Length > 1)
                {
                    order = colOrder[1].ToUpper();
                }
                if (colOrder2.Length > 1)
                {
                    order2 = colOrder2[1].ToUpper();
                }
                if (colOrder[0].ToLower() == colOrder2[0].ToLower() && order == order2)
                {
                    continue;
                }
                return false;
            }
            return true;
        }

        public virtual bool CompareReversedOrderString(string strOrder, string strOrder2)
        {
            string strReversedOrderString = GetReversedOrderString(strOrder);
            return CompareOrderString(strOrder, strReversedOrderString);
        }
        public string GetReversedOrderString(string strOrderBy)
        {
            return GetReversedOrderString(strOrderBy, false);
        }
        public string GetReversedOrderString(string strOrderBy, bool removeTName)
        {
            string formattedOrder = "";
            return GetReversedOrderString(strOrderBy, ref formattedOrder, removeTName);
        }

        public virtual string GetReversedOrderString(string strOrderBy, ref string formattedOrder, bool removeTName)
        {
            string reversedOrder = "";
            const string delimStr = ",";
            string[] aryCols = Regex.Split(strOrderBy, delimStr);

            for (int i = 0; i < aryCols.Length; i++)
            {
                if (removeTName && aryCols[i].Contains("."))
                {
                    aryCols[i] = aryCols[i].Substring(aryCols[i].IndexOf(".") + 1);
                }
                string[] colOrder = aryCols[i].Split(' ');
                string col = colOrder[0];
                string order = "ASC", order2 = "DESC";
                if (colOrder.Length > 1)
                {
                    order = colOrder[1].ToUpper();
                }
                if (-1 == order.IndexOf("DESC"))
                {
                    order = "ASC";
                    order2 = "DESC";
                }
                if (-1 == order.IndexOf("ASC"))
                {
                    order = "DESC";
                    order2 = "ASC";
                }
                formattedOrder += col + " " + order;
                reversedOrder += col + " " + order2;
                if (i < aryCols.Length - 1)
                {
                    formattedOrder += delimStr;
                    reversedOrder += delimStr;
                }
            }
            return reversedOrder;
        }
        public bool TestConnection()
        {
            return TestConnection(0);
        }
        public virtual bool TestConnection(int timeOut)
        {
            if (timeOut > 0)
            {
                int iTimeout = StrConnectionString.ToLower().IndexOf("connection Timeout=");
                if (iTimeout >= 0)
                {
                    string strTemp = StrConnectionString.Substring(iTimeout + "connection Timeout=".Length);
                    StrConnectionString = StrConnectionString.Substring(0, iTimeout);
                    strTemp = strTemp.IndexOf(";") > 0 ? strTemp.Substring(strTemp.IndexOf(";")) : "";
                    StrConnectionString += strTemp;
                }
                if (!StrConnectionString.EndsWith(";"))
                {
                    StrConnectionString += ";";
                }
                StrConnectionString += "Connection Timeout=" + timeOut + ";";
            }
            IDbConnection conn = CreateConnectionWithConnectionString();
            try
            {
                conn.Open();
                conn.Close();
                return true;
            }
            catch (Exception ex)
            {
                _lastException = ex;
                return false;
            }
        }
    }
}